package com.moli.iov.his.util;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.moli.iov.his.dto.RealTimeInfoHbaseDto;
import com.moli.iov.his.model.po.ReportSelledOnline;
import com.moli.iov.his.model.po.ReportStoreSelledOnline;
import com.moli.iov.his.model.po.ReportStoreTotalOnline;
import com.moli.iov.his.model.po.ReportTotalOnline;
import com.moli.iov.protocol.enums.CommonEnableTag;
import com.moli.iov.protocol.enums.CommonLockTag;
import com.moli.iov.protocol.enums.extend.ExtendLeasingModelTag;
import com.moli.iov.protocol.enums.realtime.ChargeStateTag;
import com.moli.iov.protocol.model.dto.realtime.ExtendVehicleStateDto;
import com.moli.iov.protocol.model.dto.realtime.VehicleAllDto;
import com.moli.iov.protocol.model.dto.realtime.VehicleGpsDto;
import com.moli.iov.util.DateUtil;
import com.moli.iov.util.GsonUtil;
import com.moli.iov.util.JsonUtils;
import com.moli.iov.util.SerializeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.*;

/**
 * @author fudh
 * @ClassNmme HisUtil
 * @date 2019/1/22 8:57
 * @Description: 历史服务模块特有的工具类
 */
@Slf4j
@Component
public class HisUtil {
    @Value("${startTime}")
     private static String startTimeStr;
    // TODO: 2019/1/22 这两个方法可以合并，后续优化的时候在合并
    public static List<ReportTotalOnline>  getOnlineDateReport(List<ReportTotalOnline> reportTotalOnlines) {
        List<ReportTotalOnline> ret = new ArrayList<>();
        Map<String, ReportTotalOnline> totalOnlineMap = new HashMap<>();
        for (ReportTotalOnline reportTotalOnline : reportTotalOnlines) {
            totalOnlineMap.put(DateUtil.format("MM-dd", reportTotalOnline.getStatTime()), reportTotalOnline);
        }
        long diff = 24 * 60 * 60 * 1000;
        for (int i = 0; i < 15; i++) {
            Date date = new Date(System.currentTimeMillis() - (15 - i) * diff);
            String monDay = DateUtil.format("MM-dd", date);
            ReportTotalOnline reportTotalOnline = totalOnlineMap.get(monDay);
            if (reportTotalOnline == null) {
                reportTotalOnline = new ReportTotalOnline();
                reportTotalOnline.setOnlineCount(0L);
                reportTotalOnline.setTotalCount(0L);
                reportTotalOnline.setStatTime(date);
            }
            ret.add(reportTotalOnline);
        }

        return ret;
    }

    public static List<ReportStoreTotalOnline>  getStoreOnlineDateReport(List<ReportStoreTotalOnline> reportTotalOnlines) {
        List<ReportStoreTotalOnline> ret = new ArrayList<>();
        Map<String, ReportStoreTotalOnline> totalOnlineMap = new HashMap<>();
        for (ReportStoreTotalOnline reportTotalOnline : reportTotalOnlines) {
            totalOnlineMap.put(DateUtil.format("MM-dd", reportTotalOnline.getStatTime()), reportTotalOnline);
        }
        long diff = 24 * 60 * 60 * 1000;
        for (int i = 0; i < 15; i++) {
            Date date = new Date(System.currentTimeMillis() - (15 - i) * diff);
            String monDay = DateUtil.format("MM-dd", date);
            ReportStoreTotalOnline reportTotalOnline = totalOnlineMap.get(monDay);
            if (reportTotalOnline == null) {
                reportTotalOnline = new ReportStoreTotalOnline();
                reportTotalOnline.setOnlineCount(0L);
                reportTotalOnline.setTotalCount(0L);
                reportTotalOnline.setStatTime(date);
            }
            ret.add(reportTotalOnline);
        }

        return ret;
    }

    public static List<ReportSelledOnline>  getSelledOnlineDateReport(List<ReportSelledOnline> reportTotalOnlines) {
        List<ReportSelledOnline> ret = new ArrayList<>();
        Map<String, ReportSelledOnline> totalOnlineMap = new HashMap<>();
        for (ReportSelledOnline reportSelledOnline : reportTotalOnlines) {
            totalOnlineMap.put(DateUtil.format("MM-dd", reportSelledOnline.getStatTime()), reportSelledOnline);
        }
        long diff = 24 * 60 * 60 * 1000;
        for (int i = 0; i < 15; i++) {
            Date date = new Date(System.currentTimeMillis() - (15 - i) * diff);
            String monDay = DateUtil.format("MM-dd", date);
            ReportSelledOnline reportSelledOnline = totalOnlineMap.get(monDay);
            if (reportSelledOnline == null) {
                reportSelledOnline = new ReportSelledOnline();
                reportSelledOnline.setSelledOnlineCount(0L);
                reportSelledOnline.setTotalCount(0L);
                reportSelledOnline.setStatTime(date);
            }
            ret.add(reportSelledOnline);
        }

        return ret;
    }

    public static List<ReportStoreSelledOnline>  getStoreSelledOnlineDateReport(List<ReportStoreSelledOnline> reportTotalOnlines) {
        List<ReportStoreSelledOnline> ret = new ArrayList<>();
        Map<String, ReportStoreSelledOnline> totalOnlineMap = new HashMap<>();
        for (ReportStoreSelledOnline reportSelledOnline : reportTotalOnlines) {
            totalOnlineMap.put(DateUtil.format("MM-dd", reportSelledOnline.getStatTime()), reportSelledOnline);
        }
        long diff = 24 * 60 * 60 * 1000;
        for (int i = 0; i < 15; i++) {
            Date date = new Date(System.currentTimeMillis() - (15 - i) * diff);
            String monDay = DateUtil.format("MM-dd", date);
            ReportStoreSelledOnline reportSelledOnline = totalOnlineMap.get(monDay);
            if (reportSelledOnline == null) {
                reportSelledOnline = new ReportStoreSelledOnline();
                reportSelledOnline.setSelledOnlineCount(0L);
                reportSelledOnline.setTotalCount(0L);
                reportSelledOnline.setStatTime(date);
            }
            ret.add(reportSelledOnline);
        }

        return ret;
    }

    public static RealTimeInfoHbaseDto ResultConvertToDto(String rowKey,byte[] messageContent){
        //入库时间
        long timeL=Long.MAX_VALUE-Long.parseLong(rowKey.substring(rowKey.indexOf("_")+1,rowKey.length()));
        //将结果封装为返回对象
        RealTimeInfoHbaseDto realTimeInfoHbaseDto = new RealTimeInfoHbaseDto();
        String jsonStr = (String) SerializeUtils.fstDeSerialize(messageContent);
        Map<String, Object> map = toggleSerialization(jsonStr,Map.class,timeL);
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = String.valueOf(entry.getKey());
            if (Contact.COLLECT_DATE.equals(key)) {
                //采集时间
                Date dateCollect = null;
                try {
                    dateCollect = DateUtil.parser(DateUtil.YEAR_SECOND,entry.getValue().toString());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                realTimeInfoHbaseDto.setCollectDate(dateCollect);
            } else if (Contact.REPORT_DATE.equals(key)) {
                //上报时间
                Date reportDate = null;
                try {
                    reportDate = DateUtil.parser(DateUtil.YEAR_SECOND,entry.getValue().toString());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                realTimeInfoHbaseDto.setReportDate(reportDate);
            } else if (Contact.VEHICLE_GPS.equals(key)) {
                //GPS数据
                VehicleGpsDto vehicleGpsDto =toggleSerialization(entry.getValue().toString(),VehicleGpsDto.class,timeL);
                realTimeInfoHbaseDto.setVehicleGps(vehicleGpsDto);
            } else if (Contact.VEHICLE_ALL.equals(key)) {
                //整车数据
                VehicleAllDto vehicleAllDto =toggleSerialization(entry.getValue().toString(),VehicleAllDto.class,timeL);
                realTimeInfoHbaseDto.setVehicleAll(vehicleAllDto);
            } else if (Contact.EXTEND_VEHICLE_STATE.equals(key)) {
                //扩展车辆状态
                ExtendVehicleStateDto extendVehicleStateDto = toggleSerialization(entry.getValue().toString(),ExtendVehicleStateDto.class,timeL);
                realTimeInfoHbaseDto.setExtendVehicleState(extendVehicleStateDto);
            }

        }
        return realTimeInfoHbaseDto;
    }

    /**
     * 查询反序列化兼容老序列化方式
     * @param str
     * @param t
     * @param time
     * @return
     */
    private static <T> T toggleSerialization(String str, Class<T> t, long time) {
        if(!StringUtils.isEmpty(startTimeStr)){
            long startTime=Long.parseLong(startTimeStr);
            if(time>startTime){
                return  JsonUtils.parse(str, t);
            }else{
               return  GsonUtil.parseJsonWithGson(str,t);
            }
        }else{
            return  GsonUtil.parseJsonWithGson(str, t);
        }
    }
}
